package qualomelhor.gwt.modules.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import qualomelhor.database.Categoria;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.ui.ListBox;

public class EditarCategoria implements EntryPoint {
	private Label lbId;
	private TextBox txtNomeCategoria;
	private CheckBox ckTranslate;
	private Label txtNivel;
	private TextBox txtEnderecoFotoCategoria;
	private TextBox txtEnderecoIcon;
	private TextBox txtOrdem;
	private CheckBox ckBloqueado;
	private VerticalPanel vertPLocale;
	private TextBox[] txtLocale;
	private TextBox[] txtTraducaoNome;
	private Label[] txtPath;
	private ListBox txtCategoriaPai;
	private int posReg = 0;
	private ArrayList<Categoria> listCategorias;
	private ISessionSuportServiceAsync serviceSupportSvc = GWT.create(ISessionSuportService.class);
	private Label lbNumRegistro;

	public static native void showDivBloqueio()  /*-{
		$doc.getElementById("divBloqueio").style.display="block";
		$doc.getElementById("divBloqueioSolido").style.display="block";
	}-*/;

	public static native void hideDivBloqueio()  /*-{
		$doc.getElementById("divBloqueio").style.display="none";
		$doc.getElementById("divBloqueioSolido").style.display="none";
	}-*/;

	@Override
	public void onModuleLoad() {
		carregaListCategorias(0L);
	}

	public void carregaListCategorias(Long idFocus) {
		carregaCategorias(true, idFocus);
	}

	private void carregaFormEditarCategoria() {
		System.out.println("listCategorias.size = " + listCategorias.size());
		RootPanel rootPanel = RootPanel.get("divCadastro");
		rootPanel.clear();
		//rootPanel.getElement().getStyle().setPosition(Position.RELATIVE);

		VerticalPanel verticalPanel = new VerticalPanel();
		rootPanel.add(verticalPanel);
		verticalPanel.setSize("100%", "300px");

		HorizontalPanel horizontalPanelNav = new HorizontalPanel();
		verticalPanel.add(horizontalPanelNav);

		Button btnNovaCategoria = new Button("Novo");
		btnNovaCategoria.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				novo();
			}
		});
		horizontalPanelNav.add(btnNovaCategoria);

		Button btnAnterior = new Button("Anterior");
		btnAnterior.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (posReg >= 0) {
					posReg--;
				}
				atualiza();
			}
		});
		horizontalPanelNav.add(btnAnterior);

		Button btnProximo = new Button("Proximo");
		btnProximo.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (posReg < listCategorias.size()) {
					posReg++;
				}
				atualiza();
			}
		});
		horizontalPanelNav.add(btnProximo);

		Button btnDeletar = new Button("Deletar");
		btnDeletar.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				deletaCategoria(listCategorias.get(posReg).getId());
			}
		});
		horizontalPanelNav.add(btnDeletar);

		lbNumRegistro = new Label("");
		horizontalPanelNav.add(lbNumRegistro);

		FlexTable tbCadastro = new FlexTable();
		verticalPanel.add(tbCadastro);
		tbCadastro.setWidth("100%");

		Label lblNewLabel = new Label("Id:");
		tbCadastro.setWidget(0, 0, lblNewLabel);

		lbId = new Label("");
		tbCadastro.setWidget(0, 1, lbId);

		Label lblNewLabel_1 = new Label("Nome Categoria:");
		tbCadastro.setWidget(1, 0, lblNewLabel_1); 
		lblNewLabel_1.setSize("138", "16");

		txtNomeCategoria = new TextBox();
		tbCadastro.setWidget(1, 1, txtNomeCategoria);

		
		Label lbTranslate = new Label("Translate:");
		tbCadastro.setWidget(2, 0, lbTranslate);
		ckTranslate = new CheckBox();
		tbCadastro.setWidget(2, 1, ckTranslate);
		
		Label lblNewLabel_2 = new Label("Id Categoria Pai:");
		tbCadastro.setWidget(3, 0, lblNewLabel_2);
		lblNewLabel_2.setSize("138", "16");

		txtCategoriaPai = new ListBox();
		txtCategoriaPai.addItem("");
		for (int i = 0; i < listCategorias.size(); i++) {
			txtCategoriaPai.addItem(listCategorias.get(i).getNomeCategoria(), listCategorias.get(i).getId().toString());
		}
		tbCadastro.setWidget(3, 1, txtCategoriaPai);
		txtCategoriaPai.setWidth("152px");

		Label lblNewLabel_3 = new Label("Nivel:");
		tbCadastro.setWidget(4, 0, lblNewLabel_3);
		lblNewLabel_3.setSize("138", "16");

		txtNivel = new Label("");
		tbCadastro.setWidget(4, 1, txtNivel);

		Label lblEnderecofotocategoria = new Label("enderecoFotoCategoria:");
		tbCadastro.setWidget(5, 0, lblEnderecofotocategoria);

		txtEnderecoFotoCategoria = new TextBox();
		tbCadastro.setWidget(5, 1, txtEnderecoFotoCategoria);

		Label lblEnderecoIcon = new Label("enderecoIcon:");
		tbCadastro.setWidget(6, 0, lblEnderecoIcon);

		txtEnderecoIcon = new TextBox();
		tbCadastro.setWidget(6, 1, txtEnderecoIcon);

		Label lblOrdem = new Label("Ordem:");
		tbCadastro.setWidget(7, 0, lblOrdem);
		lblOrdem.setSize("138", "16");

		txtOrdem = new TextBox();
		tbCadastro.setWidget(7, 1, txtOrdem);

		Label lblBloqueado = new Label("Bloqueado:");
		tbCadastro.setWidget(8, 0, lblBloqueado);
		lblBloqueado.setSize("138", "16");

		ckBloqueado = new CheckBox("");
		tbCadastro.setWidget(8, 1, ckBloqueado);

		Label lblPath = new Label("Locale / Path:");
		tbCadastro.setWidget(9, 0, lblPath);
		lblPath.setSize("138", "16");

		vertPLocale = new VerticalPanel();
		vertPLocale.setWidth("100%");
		tbCadastro.setWidget(9, 1,vertPLocale);
		

		HorizontalPanel horizontalPanel_8 = new HorizontalPanel();
		verticalPanel.add(horizontalPanel_8);
		verticalPanel.setCellHorizontalAlignment(horizontalPanel_8, HasHorizontalAlignment.ALIGN_CENTER);

		Button btnSalvar = new Button("Salvar");
		btnSalvar.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Long id = lbId.getText().equals("")?null:Long.valueOf(lbId.getText());
				Long idCategoriaPai = (txtCategoriaPai.getSelectedIndex() == -1 || txtCategoriaPai.getItemText(txtCategoriaPai.getSelectedIndex()).equals(""))?null:Long.valueOf(txtCategoriaPai.getValue(txtCategoriaPai.getSelectedIndex()));

				HashMap<String, String> mapLocale_Nome = new HashMap<String, String>(0);
				for (int i = 0; i < txtLocale.length; i++) {
					mapLocale_Nome.put(txtLocale[i].getText(), txtTraducaoNome[i].getText());
				}

				salvaCategoria(id, txtNomeCategoria.getText(), ckTranslate.getValue(), idCategoriaPai, txtEnderecoFotoCategoria.getText(), txtEnderecoIcon.getText(), Integer.valueOf(txtOrdem.getText()), ckBloqueado.getValue(), mapLocale_Nome);
			}
		});
		horizontalPanel_8.add(btnSalvar);
		horizontalPanel_8.setCellHorizontalAlignment(btnSalvar, HasHorizontalAlignment.ALIGN_CENTER);
	}

	private void carregaFormAddLocale(final Long idCategoria, String localeExemplo, String nomeTraduzidoExemplo) {

		showDivBloqueio();

		final RootPanel rootPanel = RootPanel.get("divPopupCentro");

		rootPanel.clear();
		VerticalPanel vertP = new VerticalPanel();
		vertP.setStylePrimaryName("divCemPorCento");
		vertP.addStyleName("divCenter");
    	rootPanel.add(vertP);

    	HorizontalPanel horP1 = new HorizontalPanel();
		vertP.add(horP1);
		vertP.setCellVerticalAlignment(horP1, HasVerticalAlignment.ALIGN_MIDDLE);

		final TextBox txtLocale = new TextBox();
		horP1.add(new Label("Novo Locale:"));
    	horP1.add(txtLocale);
    	txtLocale.setText(localeExemplo);
    	txtLocale.setSelectionRange(0, localeExemplo.length());

    	HorizontalPanel horP2 = new HorizontalPanel();
		vertP.add(horP2);
		vertP.setCellVerticalAlignment(horP2, HasVerticalAlignment.ALIGN_MIDDLE);
		final TextBox txtNomeTraduzido = new TextBox();
		horP1.add(new Label("Nome Traduzido:"));
    	horP1.add(txtNomeTraduzido);
    	txtNomeTraduzido.setText(nomeTraduzidoExemplo);
    	txtNomeTraduzido.setSelectionRange(0, nomeTraduzidoExemplo.length());

    	HorizontalPanel horP3 = new HorizontalPanel();
		vertP.add(horP3);
		vertP.setCellVerticalAlignment(horP3, HasVerticalAlignment.ALIGN_MIDDLE);

    	Button btnGravar = new Button("Gravar");
    	horP3.add(btnGravar);
    	btnGravar.setStylePrimaryName("btnGravar");

    	btnGravar.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				System.out.println("vai gravar novo locale .. idCategoria:[" + idCategoria + "], locale:[" + txtLocale.getText() + ", nomeTraduzido:[" + txtNomeTraduzido.getText() + "]");
				addLocale(idCategoria, txtLocale.getText(), txtNomeTraduzido.getText());
			}
		});

    	Button btnCancel = new Button ("Cancel");
    	horP3.add(btnCancel);
    	btnCancel.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				hideDivBloqueio();
				rootPanel.clear();
			}
		});
	}

	private void novo() {
		lbNumRegistro.setText("Novo Registro");
		lbId.setText("");
		txtNomeCategoria.setText("");
		ckTranslate.setValue(true);
		txtNivel.setText("0");
		txtEnderecoFotoCategoria.setText("");
		txtEnderecoIcon.setText("");
		txtOrdem.setText("0");
		ckBloqueado.setValue(false);
		txtCategoriaPai.setSelectedIndex(-1);
		
		vertPLocale.clear();
		txtLocale = new TextBox[1];
		txtPath = new Label[1];
		txtTraducaoNome = new TextBox[1];
		
		final HorizontalPanel horP = new HorizontalPanel();
		vertPLocale.add(horP);
		horP.add(new Label("Locale 0:"));
		txtLocale[0] = new TextBox();
		txtLocale[0].setWidth("30px");
		horP.add(txtLocale[0]);
		txtLocale[0].setText("default");

		horP.add(new Label("Path 0:"));
		txtPath[0] = new Label("/"); 
		horP.add(txtPath[0]);

		horP.add(new Label("    - Nome 0:"));
		txtTraducaoNome[0] = new TextBox(); 
		horP.add(txtTraducaoNome[0]);
		txtTraducaoNome[0].setText("traducao");
		
	}

	private void atualiza() {
		if (posReg == -1 || posReg == listCategorias.size()) {
			novo();
		} else {
			lbNumRegistro.setText("Registro " + (posReg + 1) + " de " + listCategorias.size());
			lbId.setText(listCategorias.get(posReg).getId().toString());
			txtNomeCategoria.setText(listCategorias.get(posReg).getNomeCategoria());
			ckTranslate.setValue(listCategorias.get(posReg).getTranslate());
			txtNivel.setText(String.valueOf(listCategorias.get(posReg).getNivel()));
			txtEnderecoFotoCategoria.setText(listCategorias.get(posReg).getEnderecoFotoCategoria());
			txtEnderecoIcon.setText(listCategorias.get(posReg).getEnderecoIcon());
			txtOrdem.setText(String.valueOf(listCategorias.get(posReg).getOrdem()));
			ckBloqueado.setValue(listCategorias.get(posReg).getBloqueado());
			
			
			vertPLocale.clear();
			txtLocale = new TextBox[listCategorias.get(posReg).getMapPath().entrySet().size()];
			txtPath = new Label[listCategorias.get(posReg).getMapPath().entrySet().size()];
			txtTraducaoNome = new TextBox[listCategorias.get(posReg).getMapPath().entrySet().size()];
			//Window.alert("numPaths = " + listCategorias.get(posReg).getMapPath().entrySet().size());
			int j = 0;
			Iterator<Entry<String, String[]>> it = listCategorias.get(posReg).getMapPath().entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, String[]> entry = it.next();
				String locale = entry.getKey();
				String path = entry.getValue()[0];
				String name = entry.getValue()[1];
				//Window.alert("locale = " + locale + ", path = " + path + ", name = " + name);

				final HorizontalPanel horP = new HorizontalPanel();
				vertPLocale.add(horP);
				horP.add(new Label("Locale " + j + ":"));
				txtLocale[j] = new TextBox();
				txtLocale[j].setWidth("30px");
				horP.add(txtLocale[j]);
				txtLocale[j].setText(locale);

				horP.add(new Label("Path " + j + ":"));
				txtPath[j] = new Label(path); 
				horP.add(txtPath[j]);

				horP.add(new Label("    - Nome " + j + ":"));
				txtTraducaoNome[j] = new TextBox(); 
				horP.add(txtTraducaoNome[j]);
				txtTraducaoNome[j].setText(name);
				//Window.alert("path " + j + " = " + txtPath[j].getText() + ", nomeTraducao = " + txtTraducaoNome[j].getText());

				if (!path.equals("default")) {
					Button btnDelLocale = new Button("Del");
					horP.add(btnDelLocale);
					btnDelLocale.setTitle("idCategoria:[" + listCategorias.get(posReg).getId() + "], Locale:[" + locale + "]!");
					btnDelLocale.addClickHandler(new ClickHandler() {
						@Override
						public void onClick(ClickEvent event) {
							Button b = (Button)event.getSource();
							Long idCategoria = Long.parseLong(b.getTitle().substring(13, b.getTitle().indexOf("], Locale:[")));
							String locale = b.getTitle().substring(b.getTitle().indexOf("Locale:[") + 8, b.getTitle().indexOf("]!"));
							deletaLocaleCategoria(idCategoria, locale);
						}
					});
				}
				j++;
			}

		    Button btnAddLocale = new Button("Novo Locale");
		    btnAddLocale.setStylePrimaryName("btnAdd");
		    vertPLocale.add(btnAddLocale);
		    btnAddLocale.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					carregaFormAddLocale(listCategorias.get(posReg).getId(), "en_US", "tradução de " + listCategorias.get(posReg).getNomeCategoria());
				}
			});

		    // marca a categoria pai no combo
			txtCategoriaPai.setSelectedIndex(-1);
			if (listCategorias.get(posReg).getCategoriaPai() != null) {
				for (int i = 0; i < txtCategoriaPai.getItemCount(); i++) {
					if (txtCategoriaPai.getValue(i).equals(listCategorias.get(posReg).getCategoriaPai().toString())) {
						txtCategoriaPai.setSelectedIndex(i);
						break;
					}
				}
			}
		}
	}

	private void salvaCategoria(final Long id, String nomeCategoria, boolean translate, Long idCategoriaPai, String enderecoFotoCategoria, String enderecoIcon, int ordem, boolean bloqueado, HashMap<String, String> mapLocale_Name) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(Boolean b) {
				if (!b) {
					Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");	
				} else {
					carregaCategorias(true, id);
					Window.alert("Salvo");
				}
			}
		};
		System.out.println("Salvando categoria: id = " + id + ", nomeCategoria = " + nomeCategoria + ", idCategoriaPai = " + idCategoriaPai + ", enderecoFotoCategoria = " + enderecoFotoCategoria + ", ordem = " + ordem + ", bloqueado = " + bloqueado);
		serviceSupportSvc.gravaCategoria(id, nomeCategoria, translate, idCategoriaPai, enderecoFotoCategoria, enderecoIcon, ordem, bloqueado, mapLocale_Name, callback);
	}

	private void deletaCategoria(Long id) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {			
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(Boolean b) {
				if (!b) {
					Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");	
				}
				carregaCategorias(true, 0L);
			}
		};
		System.out.println("Deletando categoria..");
		serviceSupportSvc.deletaCategoria(id, callback);
	}

	void carregaCategorias (boolean recarregar, final Long idFocus) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<ArrayList<Categoria>> callback = new AsyncCallback<ArrayList<Categoria>>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}
			@Override
			public void onSuccess(ArrayList<Categoria> result) {
				listCategorias = result;
				carregaFormEditarCategoria();
				if (idFocus != null && !idFocus.equals(0L)) {
					int i = 0;
					for (Categoria c: listCategorias) {
						if (c.getId().equals(idFocus)) {
							posReg = i;
							atualiza();
						} else {
							i++;
						}
					}
				}
			}
		}; 

		serviceSupportSvc.getListCategorias(recarregar, callback);
	}

	private void addLocale(final Long idCategoria, String locale, String nomeTraduzido) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {			
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});

		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(Boolean b) {
				if (!b) {
					Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");	
				} else {
					carregaListCategorias(idCategoria);
					hideDivBloqueio();
				}
			}
		};
		System.out.println("adicionando locale a categoria.." + idCategoria);
		serviceSupportSvc.addLocaleCategoria(idCategoria, locale, nomeTraduzido, callback);		
	}

	private void deletaLocaleCategoria(final Long idCategoria, String locale) {
		if (serviceSupportSvc == null) {
			serviceSupportSvc = GWT.create(ISessionSuportService.class);
		}

		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {			
			@Override
			public void onUncaughtException(Throwable e) {
				e.printStackTrace();
				System.out.println("Excecao nao tratada em Horario Carrega Sessao !!!!!!!!!!");
			}
		});
		
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");
			}

			@Override
			public void onSuccess(Boolean b) {
				if (!b) {
					Window.alert("Erro ao tentar gravar! Por favor, aperte a tecla F5 do seu teclado para atualizar!");	
				}
				carregaListCategorias(idCategoria);
			}
		};
		System.out.println("Deletando locale idCategoria = " + idCategoria + ", locale = " + locale);
		serviceSupportSvc.deletaLocaleCategoria(idCategoria, locale, callback);
	}
}